1 module hip.systems.gamepads.xbox; 2 import hip.util.system; 3 import hip.systems.gamepad; 4 5 ///Refer to https://docs.microsoft.com/en-us/uwp/api/windows.gaming.input.gamepadbuttons?view=winrt-20348 6 enum HipXboxGamepadButton : int 7 { 8 none = 0, ///No button. 9 menu = 1, ///Menu button. 10 view = 1<<1, ///View button. 11 a = 1<<2, ///A button. 12 b = 1<<3, ///B button. 13 x = 1<<4, ///X button. 14 y = 1<<5, ///Y button. 15 dPadUp = 1<<6, ///D-pad up. 16 dPadDown = 1<<7, ///D-pad down. 17 dPadLeft = 1<<8, ///D-pad left. 18 dPadRight = 1<<9, ///D-pad right. 19 leftShoulder = 1<<10, ///Left bumper. 20 rightShoulder = 1<<11, ///Right bumper. 21 leftThumbstick = 1<<12, ///Left stick. 22 rightThumbstick = 1<<13, ///Right stick. 23 paddle1 = 1<<14, ///The first paddle. 24 paddle2 = 1<<15, ///The second paddle. 25 paddle3 = 1<<16, ///The third paddle. 26 paddle4 = 1<<17, ///The fourth paddle. 27 } 28 29 30 pragma(inline, true) 31 bool isXboxGamepadButtonPressed(int gamepadState, HipXboxGamepadButton btn){return (gamepadState & btn) == btn;} 32 33 struct HipInputXboxGamepadState 34 { 35 int buttons; 36 double leftAnalogX; 37 double leftAnalogY; 38 double rightAnalogX; 39 double rightAnalogY; 40 double leftTrigger; 41 double rightTrigger; 42 } 43 44 45 //////// External API //////// 46 extern(System) __gshared 47 { 48 ubyte* function() HipGamepadCheckConnectedGamepads; 49 HipGamepadBatteryStatus function(ubyte id) HipGamepadGetBatteryStatus; 50 HipInputXboxGamepadState function(ubyte id) HipGamepadGetXboxGamepadState; 51 bool function(ubyte id) HipGamepadIsWireless; 52 ubyte function() HipGamepadQueryConnectedGamepadsCount; 53 54 void function( 55 ubyte id, 56 double leftMotor, 57 double rightMotor, 58 double leftTrigger, 59 double rightTrigger 60 ) HipGamepadSetXboxGamepadVibration; 61 } 62 63 64 65 extern(D): 66 void initXboxGamepadInput() 67 { 68 __gshared bool hasInit = false; 69 if(hasInit) 70 return; 71 version(Windows) 72 { 73 string[] errors = dllImportVariables!( 74 HipGamepadCheckConnectedGamepads, 75 HipGamepadGetBatteryStatus, 76 HipGamepadGetXboxGamepadState, 77 HipGamepadIsWireless, 78 HipGamepadQueryConnectedGamepadsCount, 79 HipGamepadSetXboxGamepadVibration 80 ); 81 foreach(err; errors) 82 { 83 import hip.console.log; 84 logln("HIPREME_ENGINE: Could not load ", err); 85 } 86 } 87 88 hasInit = true; 89 } 90 91 //////// End External API //////// 92 93 /** Engine task: 94 * Send gamepad connect and disconnect events 95 * Poll every connected gamepad every frame 96 * Should always return a neutral state for every disconnected gamepad 97 * 98 * Game task: 99 * Check gamepad count 100 * Decide what will do with connected gamepads 101 */ 102 class HipXBOXGamepad : IHipGamepadImpl 103 { 104 void poll(HipGamepad pad) 105 { 106 HipInputXboxGamepadState state = HipGamepadGetXboxGamepadState(pad.getId); 107 int b = state.buttons; 108 with(pad) 109 { 110 setAnalog(HipGamepadAnalogs.leftStick, [state.leftAnalogX, state.leftAnalogY, 1]); 111 setAnalog(HipGamepadAnalogs.rightStick, [state.rightAnalogX, state.rightAnalogY, 1]); 112 113 leftTrigger = state.leftTrigger; 114 rightTrigger = state.rightTrigger; 115 setButtonPressed(HipGamepadButton.xboxY, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.y)); 116 setButtonPressed(HipGamepadButton.xboxX, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.x)); 117 setButtonPressed(HipGamepadButton.xboxA, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.a)); 118 setButtonPressed(HipGamepadButton.xboxB, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.b)); 119 120 setButtonPressed(HipGamepadButton.dPadUp, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadUp)); 121 setButtonPressed(HipGamepadButton.dPadLeft, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadLeft)); 122 setButtonPressed(HipGamepadButton.dPadDown, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadDown)); 123 setButtonPressed(HipGamepadButton.dPadRight, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadRight)); 124 125 setButtonPressed(HipGamepadButton.left1, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.leftShoulder)); 126 setButtonPressed(HipGamepadButton.right1, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.rightShoulder)); 127 // setButtonPressed(HipGamepadButton.left2, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.pa)); 128 // setButtonPressed(HipGamepadButton.right2, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadRight)); 129 130 setButtonPressed(HipGamepadButton.left3, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.leftThumbstick)); 131 setButtonPressed(HipGamepadButton.right3, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.rightThumbstick)); 132 133 setButtonPressed(HipGamepadButton.start, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.menu)); 134 setButtonPressed(HipGamepadButton.select, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.view)); 135 } 136 } 137 138 void setVibrating(ubyte id, double leftMotor, double rightMotor, double leftTrigger, double rightTrigger) 139 { 140 HipGamepadSetXboxGamepadVibration(id, 141 leftMotor, 142 rightMotor, 143 leftTrigger, 144 rightTrigger 145 ); 146 } 147 bool isWireless(ubyte id){return HipGamepadIsWireless(id);} 148 HipGamepadBatteryStatus getBatteryStatus(ubyte id){return HipGamepadGetBatteryStatus(id);} 149 }